home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / misc / volume16 / ecu3 / part03 < prev    next >
Encoding:
Internet Message Format  |  1991-01-06  |  55.0 KB

  1. From: wht@n4hgf.uucp (Warren Tucker)
  2. Newsgroups: comp.sources.misc
  3. Subject: v16i027:  ECU async comm package rev 3.0, Part03/35
  4. Message-ID: <1991Jan6.051739.27343@sparky.IMD.Sterling.COM>
  5. Date: 6 Jan 91 05:17:39 GMT
  6. Approved: kent@sparky.imd.sterling.com
  7. X-Checksum-Snefru: 069649b7 154ae703 24017222 cc3ca58a
  8.  
  9. Submitted-by: wht@n4hgf.uucp (Warren Tucker)
  10. Posting-number: Volume 16, Issue 27
  11. Archive-name: ecu3/part03
  12.  
  13. ---- Cut Here and feed the following to sh ----
  14. #!/bin/sh
  15. # This is part 03 of ecu3
  16. if touch 2>&1 | fgrep 'amc' > /dev/null
  17.  then TOUCH=touch
  18.  else TOUCH=true
  19. fi
  20. # ============= ecufinsert.c ==============
  21. echo 'x - extracting ecufinsert.c (Text)'
  22. sed 's/^X//' << 'SHAR_EOF' > 'ecufinsert.c' &&
  23. X#define USE_XON_XOFF
  24. X/*+-------------------------------------------------------------------------
  25. X    ecufinsert.c -- insert file onto comm line
  26. X    wht@n4hgf.Mt-Park.GA.US
  27. X
  28. X  Defined functions:
  29. X    expand_filename(fname,maxlen)
  30. X    file_insert_clear_xoff()
  31. X    file_insert_to_line(narg,arg)
  32. X
  33. X--------------------------------------------------------------------------*/
  34. X/*+:EDITS:*/
  35. X/*:08-14-1990-20:40-wht@n4hgf-ecu3.00-flush old edit history */
  36. X
  37. X#include "ecu.h"
  38. X#include "ecukey.h"
  39. X
  40. Xextern int interrupt;
  41. Xextern char kbdintr;        /* current input INTR */
  42. Xextern ulong colors_current;
  43. Xextern ulong colors_alert;
  44. Xextern ulong colors_errors;
  45. X
  46. X/*+-------------------------------------------------------------------------
  47. X    expand_filename(fname) - convert fnames with shell chars
  48. X--------------------------------------------------------------------------*/
  49. Xexpand_filename(fname,maxlen)
  50. Xchar *fname;
  51. Xint maxlen;
  52. X{
  53. Xchar s256[256];
  54. Xchar *expcmd;
  55. X
  56. X    if(!find_shell_chars(fname))
  57. X        return(0);
  58. X
  59. X    sprintf(s256,"`ls %s`",fname);
  60. X    if(expand_cmd_with_wildlist(s256,&expcmd))
  61. X    {
  62. X        ff(se,"\r\nNo files match\r\n");
  63. X        return(-1);
  64. X    }
  65. X    strncpy(fname,expcmd,maxlen);
  66. X    fname[maxlen - 1] = 0;
  67. X    if(strchr(expcmd,' '))
  68. X    {
  69. X        fputs("\r\nToo many files:\r\n",se);
  70. X        fputs(expcmd,se);
  71. X        fputs("\r\n",se);
  72. X        free(expcmd);
  73. X        return(-1);
  74. X    }
  75. X    free(expcmd);
  76. X    return(0);
  77. X
  78. X}    /* end of expand_filename */
  79. X
  80. X/*+-------------------------------------------------------------------------
  81. X    file_insert_clear_xoff()
  82. X--------------------------------------------------------------------------*/
  83. Xvoid
  84. Xfile_insert_clear_xoff()
  85. X{
  86. X#ifdef USE_XON_XOFF
  87. Xulong colors_at_entry = colors_current;
  88. X
  89. X    lclear_xmtr_xoff();
  90. X#ifdef SAY_CLEARED_XOFF
  91. X    setcolor(colors_alert);
  92. X    fputs("--> local XOFF cleared\r",se);
  93. X    setcolor(colors_at_entry);
  94. X#endif
  95. X#endif
  96. X}    /* end of file_insert_clear_xoff */
  97. X
  98. X/*+-------------------------------------------------------------------------
  99. X    file_insert_to_line(narg,arg)
  100. X--------------------------------------------------------------------------*/
  101. Xfile_insert_to_line(narg,arg)
  102. Xint narg;
  103. Xchar **arg;
  104. X{
  105. Xregister rchar;
  106. Xint old_ttymode = get_ttymode();
  107. Xlong total_chars = 0L;
  108. Xlong total_lines = 0L;
  109. Xulong colors_at_entry = colors_current;
  110. Xlong timeout_msecs;
  111. XFILE *fp;
  112. Xchar file_string[512];
  113. Xchar s512[512];
  114. Xchar xmit_mode;
  115. X#ifdef USE_XON_XOFF
  116. Xint ixon;
  117. Xint ixoff;
  118. X#endif
  119. Xchar *make_char_graphic();
  120. X
  121. X    if(narg > 1)
  122. X        strncpy(s512,arg[1],sizeof(s512));    
  123. X    else
  124. X    {
  125. X        ff(se,"\r\n--> File to insert on comm line: ");
  126. X        ttygets(s512,sizeof(s512),1);
  127. X        if( (s512[0] == ESC) || (strlen(s512) == 0) )
  128. X        {
  129. X            ff(se,"--> no transmission\r\n");
  130. X            return(0);
  131. X        }
  132. X    }
  133. X    if(expand_filename(s512,sizeof(s512)))
  134. X        return(-1);
  135. X    if((fp = fopen(s512,"r")) == (FILE *)0)
  136. X    {
  137. X        ff(se,"--> ");
  138. X        perror(s512);            /* print error if we get one */
  139. X        ff(se,"\r\n");
  140. X        return(-1);
  141. X    }
  142. X
  143. X    if(narg > 1)
  144. X        ff(se,"\r\n");
  145. X
  146. X    if(narg > 2)
  147. X        xmit_mode = *arg[2];
  148. X    else
  149. X    {
  150. XASK_OPTION:
  151. X        ff(se,"--> (S)ingle line at a time\r\n");
  152. X        ff(se,"    (E)cho pacing\r\n");
  153. X        ff(se,"    (F)ull speed transmission\r\n");
  154. X        ff(se,"    (P)aced transmission (20 msec/schar)\r\n");
  155. X        ff(se,"    (Q)uit (or ESC):             ");
  156. X        xmit_mode = ttygetc(0) & 0x7F;
  157. X        if(xmit_mode > 0x20)
  158. X            fputs(make_char_graphic(xmit_mode,0),se);
  159. X        fputs("\r\n",se);
  160. X    }
  161. X
  162. X    kill_rcvr_process(SIGUSR1);
  163. X
  164. X    switch(xmit_mode = to_lower(xmit_mode))
  165. X    {
  166. X        case 's':
  167. X            setcolor(colors_alert);
  168. X            fputs("--> press SPACE to continue or ESC/'s' to stop\r\n",se);
  169. X            setcolor(colors_at_entry);
  170. X            break;
  171. X
  172. X        case 'e':
  173. X            /* fall through */
  174. X
  175. X        case 'f':
  176. X        case 'p':
  177. X            setcolor(colors_alert);
  178. X            ff(se,"--> press %s to abort\r\n",make_char_graphic(kbdintr,0));
  179. X            setcolor(colors_at_entry);
  180. X            ttymode(2);
  181. X            break;
  182. X
  183. X        case 'q':
  184. X        case ESC:
  185. X            setcolor(colors_alert);
  186. X            ff(se,"--> file insertion aborted\r\n");
  187. X            setcolor(colors_at_entry);
  188. X            fclose(fp);
  189. X            return(0);
  190. X
  191. X        default:
  192. X            ring_bell();
  193. X            fputs("\r\n",se);
  194. X            goto ASK_OPTION;
  195. X    }
  196. X
  197. X#ifdef USE_XON_XOFF
  198. X    lget_xon_xoff(&ixon,&ixoff);        /* get current line xon/xoff status */
  199. X    lxon_xoff(IXON);                    /* set it for us */
  200. X#endif
  201. X
  202. X    interrupt = 0;    /* reset SIGINT flag */
  203. X    while(fgets(file_string,sizeof(file_string),fp))
  204. X    {
  205. X    int xmit_len = strlen(file_string);
  206. X    int xmit_cr = xmit_len && (file_string[xmit_len - 1] == NL);
  207. X
  208. X        if(xmit_cr)
  209. X        {
  210. X            xmit_len--;
  211. X            file_string[xmit_len] = 0;
  212. X        }
  213. X        total_chars += xmit_len;
  214. X        total_lines++;
  215. X
  216. X/* some destinations, like BBS msg entry, take a blank line to mean
  217. Xend of message, so do not send completely blank lines */
  218. X        if(!xmit_len && xmit_cr)
  219. X        {
  220. X            lputc(' ');
  221. X            xmit_len = 1;
  222. X        }
  223. X        else if(xmit_mode == 'p')
  224. X        {
  225. X        register char *cptr = file_string;
  226. X            while(*cptr)
  227. X            {
  228. X                lputc(*cptr++);
  229. X                nap(20L);
  230. X                while(rdchk(shm->Liofd))
  231. X                {
  232. X                    rchar = lgetc_xmtr();
  233. X                    process_xmtr_rcvd_char((char)rchar,1);
  234. X                }
  235. X            }
  236. X        }
  237. X        else
  238. X            lputs(file_string);
  239. X        if(xmit_cr)
  240. X        {
  241. X            if(xmit_mode == 'p')
  242. X                nap(20L);
  243. X            lputc('\r');
  244. X            xmit_len++;
  245. X        }
  246. X
  247. X        if(interrupt)
  248. X            break;
  249. X
  250. X        switch(xmit_mode)
  251. X        {
  252. X            case 's':
  253. X                while(1)
  254. X                {
  255. X                    if(rdchk(0))
  256. X                        break;
  257. X                    rchar = lgetc_timeout(5 * 1000L);
  258. X                    if(rchar < 0)
  259. X                        file_insert_clear_xoff();
  260. X                    else
  261. X                        process_xmtr_rcvd_char((char)rchar,1);
  262. X                    if(rchar == 0x0A)
  263. X                        break;
  264. X                }
  265. X                rchar = to_lower(ttygetc(1));
  266. X                if((rchar == 's') || (rchar == ESC))
  267. X                    goto INSERT_DONE;
  268. X                break;
  269. X
  270. X            case 'e':
  271. X                timeout_msecs = 5 * 1000L;
  272. X                while(1)
  273. X                {
  274. X                    if(interrupt)
  275. X                        break;
  276. X                    rchar = lgetc_timeout(timeout_msecs);
  277. X                    if(rchar < 0)
  278. X                    {
  279. X                        if(!xmit_len)
  280. X                            break;
  281. X                        file_insert_clear_xoff();
  282. X                        timeout_msecs = 1 * 1000L;
  283. X                    }
  284. X                    else
  285. X                    {
  286. X                        process_xmtr_rcvd_char((char)rchar,1);
  287. X                        timeout_msecs = 100L;
  288. X                        if(xmit_len)
  289. X                            xmit_len--;
  290. X                    }
  291. X                    if(rchar == 0x0A)
  292. X                        break;
  293. X                }
  294. X                break;
  295. X
  296. X            case 'f':
  297. X            case 'p':
  298. X                while(rdchk(shm->Liofd))
  299. X                {
  300. X                    rchar = lgetc_xmtr();
  301. X                    process_xmtr_rcvd_char((char)rchar,1);
  302. X                }
  303. X                break;
  304. X        }
  305. X        if(interrupt)
  306. X            break;
  307. X    }
  308. X
  309. XINSERT_DONE:
  310. X
  311. X    if(interrupt)
  312. X    {
  313. X        setcolor(colors_error);
  314. X        ff(se,"--> Interrupted\r\n");
  315. X        setcolor(colors_at_entry);
  316. X    }
  317. X
  318. X    fclose(fp);
  319. X
  320. X    ttymode(old_ttymode);        /* restore old console mode */
  321. X
  322. X    while(((rchar = lgetc_timeout(200L)) > 0) && !interrupt)
  323. X        process_xmtr_rcvd_char((char)rchar,1);
  324. X
  325. X    interrupt = 0;    /* reset SIGINT flag */
  326. X    setcolor(colors_success);
  327. X    ff(se,"\r\n-->  done ... sent %ld lines, %ld characters\r\n",
  328. X                total_lines,total_chars);
  329. X    setcolor(colors_at_entry);
  330. X    lclear_xmtr_xoff();
  331. X#ifdef USE_XON_XOFF
  332. X    lxon_xoff(ixon | ixoff);    /* restore old line xon/xoff status */
  333. X#endif
  334. X    start_rcvr_process(1);
  335. X    return(0);
  336. X
  337. X}    /* end of file_insert_to_line */
  338. X
  339. X/* vi: set tabstop=4 shiftwidth=4: */
  340. X/* end of ecufinsert.c */
  341. SHAR_EOF
  342. $TOUCH -am 1224222890 'ecufinsert.c' &&
  343. chmod 0644 ecufinsert.c ||
  344. echo 'restore of ecufinsert.c failed'
  345. Wc_c="`wc -c < 'ecufinsert.c'`"
  346. test 6693 -eq "$Wc_c" ||
  347.     echo 'ecufinsert.c: original size 6693, current size' "$Wc_c"
  348. # ============= ecufkey.c ==============
  349. echo 'x - extracting ecufkey.c (Text)'
  350. sed 's/^X//' << 'SHAR_EOF' > 'ecufkey.c' &&
  351. X/*+-----------------------------------------------------------------
  352. X    ecufkey.c -- function key definition
  353. X    wht@n4hgf.Mt-Park.GA.US
  354. X
  355. X  Defined functions:
  356. X    keyset_display()
  357. X    keyset_idnum(keystr)
  358. X    keyset_idstr(KDEt)
  359. X    keyset_init()
  360. X    keyset_read(keyset_name)
  361. X    xf_to_KDEt(xf)
  362. X
  363. X------------------------------------------------------------------*/
  364. X/*+:EDITS:*/
  365. X/*:08-14-1990-20:40-wht@n4hgf-ecu3.00-flush old edit history */
  366. X
  367. X#include "ecu.h"
  368. X#include "ecukey.h"
  369. X#include "ecufkey.h"
  370. X#include "ecuxkey.h"
  371. X#include "ecufork.h"
  372. X
  373. Xextern char kbdintr;    /* current input INTR */
  374. Xextern char curr_dir[];    /* current working key defns */
  375. X
  376. XKDE        keyset_table[KDE_COUNT];
  377. Xchar keyset_name[32] = "";
  378. X
  379. XXF_KDE_NAME xf_kde_name[] =
  380. X{
  381. X    { XFcurup,    KDEk_CUU,    "CUU" },
  382. X    { XFcurdn,    KDEk_CUD,    "CUD" },
  383. X    { XFcurrt,    KDEk_CUR,    "CUR" },
  384. X    { XFcurlf,    KDEk_CUL,    "CUL" },
  385. X    { XFcur5,    KDEk_CU5,    "CU5" },
  386. X    { XFend,    KDEk_END,    "End" },
  387. X    { XFpgdn,    KDEk_PGDN,    "PgDn" },
  388. X    { XFhome,    KDEk_HOME,    "Home" },
  389. X    { XFpgup,    KDEk_PGUP,    "PgUp" },
  390. X    { XFins,    KDEk_INS,    "Ins" },
  391. X    { XF1,        KDEk_F1,    "F1" },
  392. X    { XF2,        KDEk_F2,    "F2" },
  393. X    { XF3,        KDEk_F3,    "F3" },
  394. X    { XF4,        KDEk_F4,    "F4" },
  395. X    { XF5,        KDEk_F5,    "F5" },
  396. X    { XF6,        KDEk_F6,    "F6" },
  397. X    { XF7,        KDEk_F7,    "F7" },
  398. X    { XF8,        KDEk_F8,    "F8" },
  399. X    { XF9,        KDEk_F9,    "F9" },
  400. X    { XF10,        KDEk_F10,    "F10" },
  401. X    { XF11,        KDEk_F11,    "F11" },
  402. X    { XF12,        KDEk_F12,    "F12" },
  403. X    { XFbktab,    KDEk_BKTAB,    "BkTab" },
  404. X    { 0,0,"" }
  405. X};
  406. X
  407. X/*+-------------------------------------------------------------------------
  408. X    keyset_init()
  409. X--------------------------------------------------------------------------*/
  410. Xvoid
  411. Xkeyset_init()
  412. X{
  413. Xregister itmp;
  414. Xregister KDE *tkde;
  415. Xchar *make_char_graphic();
  416. X
  417. X    for(itmp = 0; itmp < KDE_COUNT; itmp++)
  418. X    {
  419. X        tkde = &keyset_table[itmp];
  420. X        tkde->logical[0] = 0;
  421. X        tkde->count = 0;
  422. X        tkde->KDEt = (uchar)itmp;
  423. X    }
  424. X
  425. X    keyset_name[0] = 0;
  426. X
  427. X    tkde = &keyset_table[KDEk_BKTAB];
  428. X    strcpy(tkde->logical,"redisplay");
  429. X    tkde->count = KACT_REDISPLAY;
  430. X
  431. X    tkde = &keyset_table[KDEk_HOME];
  432. X    strcpy(tkde->logical,"ecu cmd");
  433. X    tkde->count = KACT_COMMAND;
  434. X
  435. X    tkde = &keyset_table[KDEk_INS];
  436. X    strcpy(tkde->logical,"local shell");
  437. X    tkde->count = KACT_LOCAL_SHELL;
  438. X
  439. X    tkde = &keyset_table[KDEk_CU5];
  440. X    strcpy(tkde->logical,"screen dump");
  441. X    tkde->str[0] = 0x7F;    /* this key is intercepted by kbd read routine */
  442. X    tkde->count = 0;
  443. X
  444. X}    /* end of keyset_init */
  445. X
  446. X/*+-------------------------------------------------------------------------
  447. X    kde_fgets(buf,bufsize,fp)
  448. X--------------------------------------------------------------------------*/
  449. Xint
  450. Xkde_fgets(buf,bufsize,fp)
  451. Xchar *buf;
  452. Xint bufsize;
  453. XFILE *fp;
  454. X{
  455. Xregister itmp;
  456. Xregister char *cptr;
  457. X
  458. X    if(!fgets(buf,bufsize,fp))
  459. X    {
  460. X        return(KDEt_EOF);
  461. X    }
  462. X
  463. X    if(!(itmp = strlen(buf)))
  464. X        return(KDEt_COMMENT);
  465. X    if(buf[itmp - 1] == '\n')
  466. X    {
  467. X        buf[itmp - 1] = 0;
  468. X        itmp--;
  469. X    }
  470. X    if(!itmp)
  471. X        return(KDEt_COMMENT);
  472. X
  473. X    cptr = buf;
  474. X    itmp = (strchr(" \t",*cptr)) ? KDEt_ENTRY : KDEt_NAME;
  475. X    while(*cptr && ((*cptr == SPACE) || (*cptr == TAB)))
  476. X        cptr++;
  477. X
  478. X    if(!*cptr || (*cptr == '#'))
  479. X        return(KDEt_COMMENT);
  480. X
  481. X    return(itmp);
  482. X    
  483. X}    /* end of kde_fgets */
  484. X
  485. X/*+-------------------------------------------------------------------------
  486. X    keyset_idnum(keystr)
  487. X--------------------------------------------------------------------------*/
  488. Xint
  489. Xkeyset_idnum(keystr)
  490. Xchar *keystr;
  491. X{
  492. Xstruct XF_KDE_NAME *xkn = xf_kde_name;
  493. X    while(xkn->xf != 0)
  494. X    {
  495. X        if(!strcmpi(xkn->name,keystr))
  496. X            return((int)xkn->kde);
  497. X        xkn++;
  498. X    }
  499. X    return(-1);
  500. X}    /* end of keyset_idnum */
  501. X
  502. X/*+-------------------------------------------------------------------------
  503. X    keyset_idstr(KDEt)
  504. X--------------------------------------------------------------------------*/
  505. Xchar *
  506. Xkeyset_idstr(KDEt)
  507. Xint KDEt;
  508. X{
  509. Xstruct XF_KDE_NAME *xkn = xf_kde_name;
  510. X
  511. X    while(xkn->xf)
  512. X    {
  513. X        if((int)xkn->kde == KDEt)
  514. X            return(xkn->name);
  515. X        xkn++;
  516. X    }
  517. X    return((char *)0);
  518. X}    /* end of keyset_idstr */
  519. X
  520. X/*+-------------------------------------------------------------------------
  521. X    xf_to_KDEt(xf)
  522. X--------------------------------------------------------------------------*/
  523. Xint
  524. Xxf_to_KDEt(xf)
  525. Xuchar xf;
  526. X{
  527. Xstruct XF_KDE_NAME *xkn = xf_kde_name;
  528. X
  529. X    while(xkn->xf)
  530. X    {
  531. X        if(xkn->xf == xf)
  532. X            return((int)xkn->kde & 0xFF);
  533. X        xkn++;
  534. X    }
  535. X    return(-1);
  536. X}    /* end of xf_to_KDEt */
  537. X
  538. X/*+-------------------------------------------------------------------------
  539. X    keyset_define_key(bufptr)
  540. X--------------------------------------------------------------------------*/
  541. Xint
  542. Xkeyset_define_key(bufptr)
  543. Xchar *bufptr;
  544. X{
  545. Xregister itmp;
  546. Xregister token_number;
  547. Xregister KDE *tkde;
  548. Xint KDEt;
  549. Xchar token_separator[2];
  550. Xchar *token;
  551. Xchar *str_token();
  552. X
  553. X    if(itmp = strlen(bufptr))    /* itmp = len; if > 0 ... */
  554. X        bufptr[--itmp] = 0;        /* ... strip trailing NL */
  555. X    if(!itmp)
  556. X        return(0);
  557. X
  558. X    if(bufptr[0] == '#')        /* comment? */
  559. X        return(0);
  560. X    if((*bufptr != 0x20) && (*bufptr != TAB))    /* if no leading space */
  561. X        return(1);
  562. X    if(*bufptr == 0)                    /* if line all blank, break */
  563. X        return(1);
  564. X
  565. X    while((*bufptr == 0x20) || (*bufptr == TAB))    /* strip lding sp/tab */
  566. X        bufptr++;
  567. X
  568. X    token_number = 0;
  569. X    strcpy(token_separator,":");
  570. X    while(token = str_token(bufptr,token_separator))
  571. X    {
  572. X        bufptr = (char *)0;    /* further calls to str_token need NULL */
  573. X        switch(token_number)
  574. X        {
  575. X            case 0:        /* first field is key identifier */
  576. X                if((KDEt = keyset_idnum(token)) < 0)
  577. X                {
  578. X                    ff(se,"  %s is not a legal key identifier\r\n",token);
  579. X                    return(0);
  580. X                }
  581. X                if(KDEt == KDEk_HOME)
  582. X                {
  583. X                    ff(se,"  HOME cannot be redefined!\r\n");
  584. X                    return(0);
  585. X                }
  586. X                if(KDEt == KDEk_CU5)
  587. X                {
  588. X                    ff(se,"  CUR5 cannot be redefined!\r\n");
  589. X                    return(0);
  590. X                }
  591. X                if(KDEt == KDEk_BKTAB)
  592. X                {
  593. X                    ff(se,"  BkTab cannot be redefined!\r\n");
  594. X                    return(0);
  595. X                }
  596. X                tkde = &keyset_table[KDEt];
  597. X                tkde->logical[0] = 0;
  598. X                tkde->count = 0;
  599. X                break;
  600. X
  601. X            case 1:        /* second field is logical key name */
  602. X                strncpy(tkde->logical,token,sizeof(tkde->logical));
  603. X                tkde->logical[sizeof(tkde->logical) - 1] = 0;
  604. X                strcpy(token_separator," \t"); /* whitespace is tok sep now */
  605. X                break;
  606. X
  607. X            default:    /* third and subsequent to define key */
  608. X                if(!strlen(token))
  609. X                    continue;
  610. X                if(tkde->count == sizeof(tkde->str))
  611. X                {
  612. X                    ff(se,"  %s: output count too long",
  613. X                        keyset_idstr(KDEt));
  614. X                    return(0);
  615. X                }
  616. X                if((itmp = ascii_to_hex(token)) < 0)
  617. X                {
  618. X                    ff(se,"  %s: '%s' invalid\r\n",
  619. X                        keyset_idstr(KDEt),token);
  620. X                    return(0);
  621. X                }
  622. X                tkde->str[tkde->count] = itmp;
  623. X                tkde->count++;
  624. X                break;
  625. X        }    /* end of switch(token_number) */
  626. X        token_number++;
  627. X    }        /* end while not end of record */
  628. X
  629. X    return(0);
  630. X}    /* end of keyset_define_key */
  631. X
  632. X/*+-------------------------------------------------------------------------
  633. X    keyset_read(name)
  634. Xreturns 0 on success, -1 if no .ecu/keys, -2 if no 'name'
  635. X--------------------------------------------------------------------------*/
  636. Xint
  637. Xkeyset_read(name)
  638. Xchar *name;
  639. X{
  640. Xregister itmp;
  641. Xregister char *cptr;
  642. Xstatic char ecukeys_name[128];
  643. Xchar readkde_buf[128];
  644. XFILE *fp_keys;
  645. X
  646. X    if(!ecukeys_name[0])
  647. X    {
  648. X        get_home_dir(ecukeys_name);
  649. X        strcat(ecukeys_name,"/.ecu/keys");
  650. X    }
  651. X
  652. X    if((fp_keys = fopen(ecukeys_name,"r")) == NULL)
  653. X        return(-1);
  654. X
  655. X/* find keyset name */
  656. X    while(fgets(readkde_buf,sizeof(readkde_buf),fp_keys) != NULL)
  657. X    {
  658. X        if(readkde_buf[0] == '#')        /* comment? */
  659. X            continue;
  660. X        if(itmp = strlen(readkde_buf))    /* itmp = len; if > 0 ... */
  661. X            readkde_buf[--itmp] = 0;    /* ... strip trailing NL */
  662. X        if(!itmp)
  663. X            continue;
  664. X        if(strcmp(readkde_buf,name) == 0)
  665. X        {
  666. X            itmp = 1;        /* indicate success */
  667. X            break;
  668. X        }
  669. X        itmp = 0;            /* if loop terminates w/o find, failure */
  670. X    }
  671. X    if(!itmp)
  672. X    {
  673. X        fclose(fp_keys);
  674. X        return(-2);
  675. X    }
  676. X
  677. X    keyset_init();    /* clear any previous key defns */
  678. X
  679. X/* read past any other keyset names matching this set */
  680. X    while(fgets(readkde_buf,sizeof(readkde_buf),fp_keys) != NULL)
  681. X    {
  682. X        cptr = readkde_buf;                /* first call to str_token, -> buff */
  683. X        if((*cptr == 0x20) || (*cptr == TAB))    /* if leading space */
  684. X        {
  685. X            (void)keyset_define_key(cptr);
  686. X            break;
  687. X        }
  688. X    }
  689. X
  690. X/* we found the definition ... read it */
  691. X    while(fgets(readkde_buf,sizeof(readkde_buf),fp_keys) != NULL)
  692. X    {
  693. X        if(keyset_define_key(readkde_buf))
  694. X            break;
  695. X    }
  696. X
  697. X    strncpy(keyset_name,name,sizeof(keyset_name));
  698. X    keyset_name[sizeof(keyset_name) - 1] = 0;
  699. X    fclose(fp_keys);
  700. X    return(0);
  701. X}    /* end of keyset_read */
  702. X
  703. X/*+-------------------------------------------------------------------------
  704. X    ffso(str)
  705. X--------------------------------------------------------------------------*/
  706. Xvoid
  707. Xffso(str)
  708. Xchar *str;
  709. X{
  710. X    tcap_stand_out();
  711. X    fputs(str,se);
  712. X    tcap_stand_end();
  713. X}    /* end of ffso */
  714. X
  715. X/*+-------------------------------------------------------------------------
  716. X    keyset_display()
  717. X
  718. X F1  xxxxx  F2   xxxxx   HOME xxxxx  PGUP xxxxx
  719. X F3  xxxxx  F4   xxxxx   END  xxxxx  PGDN xxxxx
  720. X F5  xxxxx  F6   xxxxx   INS  xxxxx  CUR5 xxxxx
  721. X F7  xxxxx  F8   xxxxx   BkTab xxxxx
  722. X F9  xxxxx  F10  xxxxx   CUR^ xxxxx  CUR> xxxxx
  723. X F11 xxxxx  F12  xxxxx   CUR< xxxxx  CURv xxxxx
  724. X--------------------------------------------------------------------------*/
  725. Xvoid
  726. Xkeyset_display()
  727. X{
  728. Xregister itmp;
  729. Xregister itmp2;
  730. Xint clen1 = 0;
  731. Xchar cfmt1[32];
  732. Xint clen2 = 0;
  733. Xchar cfmt2[32];
  734. Xint clen3 = 0;
  735. Xchar cfmt3[32];
  736. Xchar cfmt4[8];
  737. X
  738. X    if(!keyset_name[0])
  739. X    {
  740. X        keyset_init();
  741. X        ff(se,"   no key definition active\r\n\r\n");
  742. X        ff(se,"HOME - command prefix\r\n");
  743. X        ff(se,"BkTab  - redisplay receiver screen\r\n");
  744. X        ff(se,"cursor down - local shell in %s\r\n",curr_dir);
  745. X        fputs("\r\n",se);
  746. X    }
  747. X    else
  748. X    {
  749. X        for(itmp = 0; itmp < KDE_COUNT; itmp++)
  750. X        {
  751. X        register KDE *tkde = &keyset_table[itmp];
  752. X            itmp2 = strlen(tkde->logical);
  753. X            switch(itmp)
  754. X            {
  755. X                case KDEk_F1: case KDEk_F3: case KDEk_F5: case KDEk_F7:
  756. X                case KDEk_F9: case KDEk_F11:
  757. X                    if(clen1 < itmp2)
  758. X                        clen1 = itmp2;
  759. X                    break;
  760. X
  761. X                case KDEk_F2: case KDEk_F4: case KDEk_F6: case KDEk_F8:
  762. X                case KDEk_F10: case KDEk_F12:
  763. X                    if(clen2 < itmp2)
  764. X                        clen2 = itmp2;
  765. X                    break;
  766. X
  767. X                case KDEk_HOME: case KDEk_END: case KDEk_INS:
  768. X                case KDEk_CUU: case KDEk_CUL:
  769. X                    if(clen3 < itmp2)
  770. X                        clen3 = itmp2;
  771. X                    break;
  772. X            }
  773. X        }
  774. X        sprintf(cfmt1," %%-%d.%ds",clen1,clen1);
  775. X        sprintf(cfmt2," %%-%d.%ds",clen2,clen2);
  776. X        sprintf(cfmt3," %%-%d.%ds",clen3,clen3);
  777. X        strcpy(cfmt4," %s");
  778. X        ff(se,"   key definition: %s\r\n\r\n",keyset_name);
  779. X
  780. X        ffso(" F1  ");ff(se,cfmt1,keyset_table[KDEk_F1].logical);
  781. X        fputs("  ",se);
  782. X        ffso(" F2  ");ff(se,cfmt2,keyset_table[KDEk_F2].logical);
  783. X        fputs("  ",se);
  784. X        ffso(" Home ");ff(se,cfmt3,keyset_table[KDEk_HOME].logical);
  785. X        fputs("  ",se);
  786. X        ffso(" PgUp ");ff(se,cfmt4,keyset_table[KDEk_PGUP].logical);
  787. X        fputs("\r\n",se);
  788. X
  789. X        ffso(" F3  ");ff(se,cfmt1,keyset_table[KDEk_F3].logical);
  790. X        fputs("  ",se);
  791. X        ffso(" F4  ");ff(se,cfmt2,keyset_table[KDEk_F4].logical);
  792. X        fputs("  ",se);
  793. X        ffso(" End  ");ff(se,cfmt3,keyset_table[KDEk_END].logical);
  794. X        fputs("  ",se);
  795. X        ffso(" PgDn ");ff(se,cfmt4,keyset_table[KDEk_PGDN].logical);
  796. X        fputs("\r\n",se);
  797. X
  798. X        ffso(" F5  ");ff(se,cfmt1,keyset_table[KDEk_F5].logical);
  799. X        fputs("  ",se);
  800. X        ffso(" F6  ");ff(se,cfmt2,keyset_table[KDEk_F6].logical);
  801. X        fputs("  ",se);
  802. X        ffso(" Ins  ");ff(se,cfmt3,keyset_table[KDEk_INS].logical);
  803. X        fputs("  ",se);
  804. X        ffso(" CUR5 ");ff(se,cfmt4,keyset_table[KDEk_CU5].logical);
  805. X        fputs("\r\n",se);
  806. X
  807. X        ffso(" F7  ");ff(se,cfmt1,keyset_table[KDEk_F7].logical);
  808. X        fputs("  ",se);
  809. X        ffso(" F8  ");ff(se,cfmt2,keyset_table[KDEk_F8].logical);
  810. X        fputs("  ",se);
  811. X        ffso(" BkTab");ff(se,cfmt3,keyset_table[KDEk_BKTAB].logical);
  812. X        fputs("\r\n",se);
  813. X
  814. X        ffso(" F9  ");ff(se,cfmt1,keyset_table[KDEk_F9].logical);
  815. X        fputs("  ",se);
  816. X        ffso(" F10 ");ff(se,cfmt2,keyset_table[KDEk_F10].logical);
  817. X        fputs("  ",se);
  818. X        ffso(" CUR^ ");ff(se,cfmt3,keyset_table[KDEk_CUU].logical);
  819. X        fputs("  ",se);
  820. X        ffso(" CUR> ");ff(se,cfmt4,keyset_table[KDEk_CUR].logical);
  821. X        fputs("\r\n",se);
  822. X
  823. X        ffso(" F11 ");ff(se,cfmt1,keyset_table[KDEk_F11].logical);
  824. X        fputs("  ",se);
  825. X        ffso(" F12 ");ff(se,cfmt2,keyset_table[KDEk_F12].logical);
  826. X        fputs("  ",se);
  827. X        ffso(" CUR< ");ff(se,cfmt3,keyset_table[KDEk_CUL].logical);
  828. X        fputs("  ",se);
  829. X        ffso(" CURv ");ff(se,cfmt4,keyset_table[KDEk_CUD].logical);
  830. X        fputs("\r\n\r\n",se);
  831. X    }
  832. X
  833. X}    /* end of keyset_display */
  834. X
  835. X/* end of ecufkey.c */
  836. X/* vi: set tabstop=4 shiftwidth=4: */
  837. SHAR_EOF
  838. $TOUCH -am 1224222890 'ecufkey.c' &&
  839. chmod 0644 ecufkey.c ||
  840. echo 'restore of ecufkey.c failed'
  841. Wc_c="`wc -c < 'ecufkey.c'`"
  842. test 12100 -eq "$Wc_c" ||
  843.     echo 'ecufkey.c: original size 12100, current size' "$Wc_c"
  844. # ============= ecufork.c ==============
  845. echo 'x - extracting ecufork.c (Text)'
  846. sed 's/^X//' << 'SHAR_EOF' > 'ecufork.c' &&
  847. X/*+-------------------------------------------------------------------------
  848. X    ecufork.c -- ecu spawning ground
  849. X    wht@n4hgf.Mt-Park.GA.US
  850. X
  851. X  Defined functions:
  852. X    exec_cmd(cmdstr)
  853. X    expand_cmd_with_wildlist(cmd,expcmd)
  854. X    find_executable(progname)
  855. X    is_executable(progname)
  856. X    shell(shellcmd)
  857. X    smart_fork()
  858. X
  859. X--------------------------------------------------------------------------*/
  860. X/*+:EDITS:*/
  861. X/*:09-19-1990-19:36-wht@n4hgf-ecu_log_event now gets pid for log from caller */
  862. X/*:08-14-1990-20:40-wht@n4hgf-ecu3.00-flush old edit history */
  863. X
  864. X#include "ecu.h"
  865. X#include "ecufork.h"
  866. X
  867. Xextern int rcvr_pid;
  868. Xextern int last_child_wait_status;
  869. Xextern int last_child_wait_pid;
  870. X
  871. X/*+-------------------------------------------------------------------------
  872. X    smart_fork()
  873. X--------------------------------------------------------------------------*/
  874. Xint
  875. Xsmart_fork()
  876. X{
  877. Xregister int count = 5;
  878. Xregister int pid;
  879. X
  880. X    while(count--)
  881. X    {
  882. X        if((pid = fork()) >= 0)
  883. X            return(pid);
  884. X        if(count)
  885. X            nap(40L);
  886. X    }
  887. X    return(-1);
  888. X}    /* end of smart_fork */
  889. X
  890. X/*+-----------------------------------------------------------------------
  891. X    shell(shellcmd)
  892. X
  893. X  param 'shellcmd' is a shell command prefixed with either
  894. X  a '!', '$', '>' character.
  895. X
  896. X  '!' causes the command to run as a normal subshell of a process.
  897. X  '$' causes the communications line to be stdin and stdout
  898. X      for the spawned shell
  899. X  '>' causes spawned shell to receive exactly sames files as ecu
  900. X------------------------------------------------------------------------*/
  901. Xvoid
  902. Xshell(shellcmd)
  903. Xchar *shellcmd;
  904. X{
  905. Xregister shellpid;
  906. Xregister itmp;
  907. Xregister char *cptr;
  908. Xchar s40[40];
  909. Xint wait_status;
  910. X
  911. Xint rcvr_alive = (rcvr_pid > 0);
  912. Xchar *getenv();
  913. X
  914. X    if(rcvr_alive)
  915. X        kill_rcvr_process(SIGUSR1);        /* stop receiver process gracefully */
  916. X
  917. X    signal(SIGINT,SIG_IGN);
  918. X    signal(SIGTERM,SIG_IGN);
  919. X    signal(SIGUSR1,SIG_IGN);
  920. X    signal(SIGUSR2,SIG_IGN);
  921. X    signal(SIGCLD,SIG_DFL);
  922. X
  923. X    if((shellpid = smart_fork()) < 0)
  924. X    {
  925. X        ff(se,"Cannot fork\r\n");
  926. X        if(rcvr_alive)
  927. X            start_rcvr_process(1);
  928. X        xmtr_signals();
  929. X        return;
  930. X    }
  931. X
  932. X    ttymode(0);                   /* set canonical tty mode */
  933. X    if(shellpid == 0)            /* we are the spawned (going to call shell) */
  934. X    {
  935. X        if(*shellcmd != '>')    /* '>' prefix means leave fd's alone! */
  936. X        {
  937. X            /* Hook-up our "standard output" to either the tty or
  938. X             * the line as appropriate for '!' or '$' */
  939. X            close(TTYOUT);
  940. X            fcntl(((*shellcmd == '$') ? shm->Liofd : TTYERR),F_DUPFD,TTYOUT);
  941. X            if(*shellcmd == '$')
  942. X            {
  943. X                close(TTYIN);
  944. X                fcntl(shm->Liofd,F_DUPFD,TTYIN);
  945. X            }
  946. X            close(shm->Liofd);
  947. X        }
  948. X
  949. X        child_signals();        /* signals for child */
  950. X
  951. X        if(*shellcmd == '!')
  952. X        {
  953. X            cptr = getenv("SHELL");
  954. X            if(cptr == (char *)0)
  955. X                cptr = "/bin/csh";
  956. X        }
  957. X        else
  958. X            cptr = "/bin/sh";
  959. X
  960. X        shellcmd++;
  961. X        child_signals();
  962. X        if(ulindex(cptr,"csh") > -1)
  963. X        {
  964. X            if(*shellcmd == '\0')
  965. X                execl(cptr,"csh",(char *)0);
  966. X            else
  967. X                execl(cptr,"csh","-c",shellcmd,(char *)0);
  968. X        }
  969. X        else
  970. X        {
  971. X            if(*shellcmd == '\0')
  972. X                execl(cptr,"sh",(char *)0);
  973. X            else
  974. X                execl(cptr,"sh","-c",shellcmd,(char *)0);
  975. X        }
  976. X
  977. X        ff(se,"cannot execute %s\r\n",cptr);    /* should not get here */
  978. X        _exit(255);                                /* end of spawned process */
  979. X    }    /* end of if child process */
  980. X
  981. X#if defined(FORK_DEBUG)
  982. X    sprintf(s40,"DEBUG fork shell pid %d",shellpid);
  983. X    ecu_log_event(getpid(),s40); /* shell */
  984. X#endif
  985. X
  986. X    while(((itmp = wait(&wait_status)) != shellpid) && (itmp != -1))
  987. X        ;
  988. X    last_child_wait_status = wait_status;
  989. X    last_child_wait_pid = shellpid;
  990. X
  991. X    xmtr_signals();            /* restore standard xmtr signals */
  992. X    ttymode(1);                /* control tty back to raw mode */
  993. X
  994. X/* any comm program will probably doodle with the line characteristics. */
  995. X/* we want to make sure they are restored to normal */
  996. X    lreset_ksr();            /* restore comm line params */
  997. X
  998. X    if(rcvr_alive)
  999. X        start_rcvr_process(1);
  1000. X
  1001. X}    /* end of shell */
  1002. X
  1003. X/*+-------------------------------------------------------------------------
  1004. X    is_executable(progname)
  1005. X--------------------------------------------------------------------------*/
  1006. Xis_executable(progname)
  1007. Xchar *progname;
  1008. X{
  1009. Xstruct stat ss;
  1010. X
  1011. X    if(stat(progname,&ss) < 0)            /* if cannot stat, flunk */
  1012. X        return(0);
  1013. X    if((ss.st_mode & 0111) == 0)        /* if no --x--x--x, flunk */
  1014. X        return(0);
  1015. X    return(1);    /* whew, this OUGHT to work */
  1016. X
  1017. X}    /* end of is_executable */
  1018. X
  1019. X/*+-------------------------------------------------------------------------
  1020. X    find_executable(progname)
  1021. XPATH=':/usr/wht/bin:/bin:/usr/bin:/usr/wht/bin:/etc/tuckerware' len=56
  1022. X--------------------------------------------------------------------------*/
  1023. Xchar *
  1024. Xfind_executable(progname)
  1025. Xchar *progname;
  1026. X{
  1027. Xregister itmp;
  1028. Xstatic char *path_buf = (char *)0;
  1029. X#define PATHNAME_QUAN 32
  1030. Xstatic char *path_name[PATHNAME_QUAN + 1];
  1031. Xstatic char rtn_path[256];
  1032. Xstatic int path_count = 0;
  1033. Xchar *cptr;
  1034. Xchar *getenv();
  1035. X
  1036. X    if(path_buf == (char *)0)
  1037. X    {
  1038. X        if((cptr = getenv("PATH")) == (char *)0)
  1039. X            return(cptr);
  1040. X        if(!(path_buf = malloc(strlen(cptr) + 1)))
  1041. X            return((char *)0);
  1042. X        strcpy(path_buf,cptr);
  1043. X        path_name[PATHNAME_QUAN + 1] = (char *)0;
  1044. X        cptr = path_buf;
  1045. X        for(path_count = 0; path_count < PATHNAME_QUAN; path_count++)
  1046. X        {
  1047. X            if(*cptr == 0)
  1048. X                break;
  1049. X            path_name[path_count] = cptr;
  1050. X            while((*cptr != ':') && (*cptr != 0))
  1051. X                cptr++;
  1052. X            if(*cptr == ':')
  1053. X                *cptr++ = 0;
  1054. X        }
  1055. X    }    /* end of get and process path env variable */
  1056. X
  1057. X/* look for executable */
  1058. X    for(itmp = 0; itmp < path_count; itmp++)
  1059. X    {
  1060. X        if(*path_name[itmp] == 0)    /* if null path (./) */
  1061. X            strcpy(rtn_path,"./");
  1062. X        else
  1063. X            sprintf(rtn_path,"%s/",path_name[itmp]);
  1064. X        strcat(rtn_path,progname);
  1065. X        if(is_executable(rtn_path))
  1066. X            return(rtn_path);
  1067. X    }
  1068. X    return((char *)0);
  1069. X}    /* end of find_executable */
  1070. X
  1071. X/*+-------------------------------------------------------------------------
  1072. X    exec_cmd(cmdstr) - execute an arbitrary program with arguments
  1073. Xkills rcvr process if alive and restarts it when done if was alive
  1074. X--------------------------------------------------------------------------*/
  1075. Xexec_cmd(cmdstr)
  1076. Xchar *cmdstr;
  1077. X{
  1078. Xchar *cmdpath;
  1079. X#define MAX_EXEC_ARG 512
  1080. Xchar *cmdargv[MAX_EXEC_ARG];
  1081. Xint itmp;
  1082. Xint execpid;
  1083. Xint rcvr_alive = (rcvr_pid > 0);
  1084. Xint old_ttymode = get_ttymode();
  1085. Xint wait_status = 0;
  1086. Xextern int errno;
  1087. Xchar *strrchr();
  1088. X
  1089. X#if defined(FORK_DEBUG)
  1090. Xchar s80[80];
  1091. X    strcpy(s80,"DEBUG exec ");
  1092. X    strncat(s80,cmdstr,sizeof(s80)-12);
  1093. X    s80[sizeof(s80)-12] = 0;
  1094. X    ecu_log_event(getpid(),s80);
  1095. X#endif
  1096. X
  1097. X    build_arg_array(cmdstr,cmdargv,MAX_EXEC_ARG,&itmp);
  1098. X    if(itmp == MAX_EXEC_ARG)
  1099. X    {
  1100. X        ff(se,"Too many arguments to command\r\n");
  1101. X        return(-1);
  1102. X    }
  1103. X    else if(!itmp)
  1104. X    {
  1105. X        ff(se,"null command\r\n");
  1106. X        return(-1);
  1107. X    }
  1108. X
  1109. X    if(*cmdargv[0] == '/')
  1110. X    {
  1111. X        cmdpath = cmdargv[0];
  1112. X        cmdargv[0] = strrchr(cmdargv[0],'/') + 1;
  1113. X    }
  1114. X    else
  1115. X    {
  1116. X        if((cmdpath = find_executable(cmdargv[0])) == (char *)0)
  1117. X        {
  1118. X            ff(se,"Cannot find %s\r\n",cmdargv[0]);
  1119. X            return(-1);
  1120. X        }
  1121. X    }
  1122. X
  1123. X    if(rcvr_alive)
  1124. X        kill_rcvr_process(SIGUSR1);        /* stop receiver process gracefully */
  1125. X
  1126. X/* this code executed by the father (forking) process */
  1127. X/* wait on death of child (morbid in life, but ok here) */
  1128. X
  1129. X    signal(SIGINT,SIG_IGN);
  1130. X    signal(SIGTERM,SIG_IGN);
  1131. X    signal(SIGUSR1,SIG_IGN);
  1132. X    signal(SIGUSR2,SIG_IGN);
  1133. X    signal(SIGCLD,SIG_DFL);
  1134. X
  1135. X    if((execpid = smart_fork()) < 0)
  1136. X    {
  1137. X        ff(se,"Cannot fork\r\n");
  1138. X        if(rcvr_alive)
  1139. X            start_rcvr_process(1);
  1140. X        xmtr_signals();
  1141. X        return(-1);
  1142. X    }
  1143. X
  1144. X    if(execpid == 0)            /* we are the spawned (going to call exec) */
  1145. X    {
  1146. X        ttymode(0);               /* set canonical tty mode */
  1147. X        child_signals();
  1148. X        execv(cmdpath,cmdargv);
  1149. X        perror(cmdpath);
  1150. X        exit(255);                /* end of spawned process */
  1151. X    }    /* end of if child process */
  1152. X
  1153. X    wait_status = 0;
  1154. X    while(((itmp = wait(&wait_status)) != execpid) && (itmp != -1))
  1155. X        ;
  1156. X    last_child_wait_status = wait_status;
  1157. X    last_child_wait_pid = execpid;
  1158. X
  1159. X/* resume our normally scheduled program */
  1160. X    lreset_ksr();                /* restore comm line params */
  1161. X    ttymode(old_ttymode);        /* control tty back to original */
  1162. X    if(rcvr_alive)
  1163. X        start_rcvr_process(1);
  1164. X    xmtr_signals();
  1165. X    return(last_child_wait_status);
  1166. X
  1167. X}    /* end of exec_cmd */
  1168. X
  1169. X/*+-------------------------------------------------------------------------
  1170. X    expand_cmd_with_wildlist(cmd,&expcmd)
  1171. Xif return -1, error, expcmd has error message (static message)
  1172. Xif return 0, cmd has been expanded, expcmd must be free()'d when done
  1173. X--------------------------------------------------------------------------*/
  1174. Xexpand_cmd_with_wildlist(cmd,expcmd)
  1175. Xchar *cmd;
  1176. Xchar **expcmd;
  1177. X{
  1178. Xregister char *cptr;
  1179. X#define P_READ 0
  1180. X#define P_WRITE 1
  1181. Xint pipe_pid;
  1182. Xint stdout_pipe[2];
  1183. Xint stderr_pipe[2];
  1184. Xint count;
  1185. Xint itmp;
  1186. Xint wait_status;
  1187. Xint rcvr_alive = (rcvr_pid > 0);
  1188. Xchar *echo_cmd;
  1189. Xstatic char s132[132];
  1190. Xextern int errno;
  1191. Xextern char *sys_errlist[];
  1192. Xchar *strchr();
  1193. Xstatic char *pipe_err_msg = "system error: no pipe";
  1194. Xstatic char *mem_err_msg = "system error: no memory";
  1195. X
  1196. X    if(strchr(cmd,'<') || strchr(cmd,'>') || strchr(cmd,'&'))
  1197. X    {
  1198. X        *expcmd = "illegal characters: '<', '>' or '&'";
  1199. X        return(-1);
  1200. X    }
  1201. X
  1202. X    if(pipe(stdout_pipe) < 0)
  1203. X    {
  1204. X        *expcmd = pipe_err_msg;
  1205. X        return(-1);
  1206. X    }
  1207. X    if(pipe(stderr_pipe) < 0)
  1208. X    {
  1209. X        close(stdout_pipe[P_READ]);
  1210. X        close(stdout_pipe[P_WRITE]);
  1211. X        *expcmd = pipe_err_msg;
  1212. X        return(-1);
  1213. X    }
  1214. X    if(!(echo_cmd = malloc(strlen(cmd) + 10)))
  1215. X    {
  1216. X        close(stdout_pipe[P_READ]);
  1217. X        close(stdout_pipe[P_WRITE]);
  1218. X        close(stderr_pipe[P_READ]);
  1219. X        close(stderr_pipe[P_WRITE]);
  1220. X        *expcmd = mem_err_msg;
  1221. X        return(-1);
  1222. X    }
  1223. X
  1224. X    strcpy(echo_cmd,"echo ");
  1225. X    strcat(echo_cmd,cmd);
  1226. X
  1227. X
  1228. X    if(rcvr_alive)
  1229. X        kill_rcvr_process(SIGUSR1);        /* stop receiver process gracefully */
  1230. X
  1231. X    signal(SIGINT,SIG_IGN);
  1232. X    signal(SIGTERM,SIG_IGN);
  1233. X    signal(SIGUSR1,SIG_IGN);
  1234. X    signal(SIGUSR2,SIG_IGN);
  1235. X    signal(SIGCLD,SIG_DFL);
  1236. X
  1237. X    if((pipe_pid = smart_fork()) == 0)
  1238. X    {
  1239. X    int null = open("/dev/null",O_WRONLY,0);
  1240. X
  1241. X        close(stdout_pipe[P_READ]);
  1242. X        close(TTYOUT);
  1243. X        dup(stdout_pipe[P_WRITE]);
  1244. X        close(stdout_pipe[P_WRITE]);
  1245. X        close(TTYERR);
  1246. X        dup(stderr_pipe[P_WRITE]);
  1247. X        close(stderr_pipe[P_WRITE]);
  1248. X        close(null);
  1249. X        child_signals();
  1250. X        execl("/bin/csh","csh","-e","-f","-c",echo_cmd,(char *)0);
  1251. X        _exit(255);
  1252. X    }
  1253. X#if defined(FORK_DEBUG)
  1254. X    sprintf(s132,"DEBUG expand pid %d",pipe_pid);
  1255. X    ecu_log_event(getpid(),s132);        /* expand_cmd_with_wildlist */
  1256. X#endif
  1257. X
  1258. X    free(echo_cmd);
  1259. X
  1260. X    close(stdout_pipe[P_WRITE]);
  1261. X    close(stderr_pipe[P_WRITE]);
  1262. X    if(pipe_pid == -1)
  1263. X    {
  1264. X        close(stdout_pipe[P_READ]);
  1265. X        close(stderr_pipe[P_READ]);
  1266. X        *expcmd = "could not fork";
  1267. X        if(rcvr_alive)
  1268. X            start_rcvr_process(0);
  1269. X        xmtr_signals();
  1270. X        return(-1);
  1271. X    }
  1272. X
  1273. X    if(!(*expcmd = malloc(5120)))
  1274. X    {
  1275. X        close(stdout_pipe[P_READ]);
  1276. X        close(stderr_pipe[P_READ]);
  1277. X        kill(pipe_pid,SIGKILL);
  1278. X        *expcmd = mem_err_msg;
  1279. X        if(rcvr_alive)
  1280. X            start_rcvr_process(0);
  1281. X        return(-1);
  1282. X    }
  1283. X
  1284. X    cptr = *expcmd;
  1285. X    while((count = read(stdout_pipe[P_READ],cptr,64)) != 0)
  1286. X    {
  1287. X        if(count < 0)
  1288. X        {
  1289. X            if(errno == EINTR)
  1290. X            {
  1291. X                errno = 0;
  1292. X                continue;
  1293. X            }
  1294. X            free(*expcmd);
  1295. X            kill(pipe_pid,SIGKILL);
  1296. X            close(stdout_pipe[P_READ]);
  1297. X            close(stderr_pipe[P_READ]);
  1298. X            *expcmd = "error reading wild list expansion";
  1299. X            if(rcvr_alive)
  1300. X                start_rcvr_process(0);
  1301. X            return(-1);
  1302. X        }
  1303. X        cptr += count;
  1304. X        *cptr = 0;
  1305. X        if(*(cptr - 1) == '\n')
  1306. X        {
  1307. X            *(cptr - 1) = 0;
  1308. X            break;
  1309. X        }
  1310. X    }
  1311. X    close(stdout_pipe[P_READ]);
  1312. X    if(!strlen(*expcmd))
  1313. X    {
  1314. X        free(*expcmd);
  1315. X        count = read(stderr_pipe[P_READ],s132,sizeof(s132) - 1);
  1316. X        if(count < 0)
  1317. X            strcpy(s132,sys_errlist[errno]);
  1318. X        else
  1319. X            s132[count] = 0;
  1320. X        if(s132[count - 1] == '\n')
  1321. X            s132[count - 1] = 0;
  1322. X        close(stderr_pipe[P_READ]);
  1323. X        if(strncmp(s132,"echo: ",6))
  1324. X            *expcmd = s132;
  1325. X        else
  1326. X            *expcmd = s132 + 6;
  1327. X        if(rcvr_alive)
  1328. X            start_rcvr_process(0);
  1329. X        return(-1);
  1330. X    }
  1331. X
  1332. X    wait_status = 0;
  1333. X    while(((itmp = wait(&wait_status)) != pipe_pid) && (itmp != -1))
  1334. X        ;
  1335. X
  1336. X    xmtr_signals();
  1337. X    if(wait_status)
  1338. X    {
  1339. X        free(*expcmd);
  1340. X        count = read(stderr_pipe[P_READ],s132,sizeof(s132) - 1);
  1341. X        if(count < 0)
  1342. X            strcpy(s132,sys_errlist[errno]);
  1343. X        else
  1344. X            s132[count] = 0;
  1345. X        if(s132[count - 1] == '\n')
  1346. X            s132[count - 1] = 0;
  1347. X        close(stderr_pipe[P_READ]);
  1348. X        if(strncmp(s132,"echo: ",6))
  1349. X            *expcmd = s132;
  1350. X        else
  1351. X            *expcmd = s132 + 6;
  1352. X        if(rcvr_alive)
  1353. X            start_rcvr_process(0);
  1354. X        return(-1);
  1355. X    }
  1356. X    close(stderr_pipe[P_READ]);
  1357. X
  1358. X    if(rcvr_alive)
  1359. X        start_rcvr_process(0);
  1360. X    return(0);
  1361. X}    /* end of expand_cmd_with_wildlist */
  1362. X/* vi: set tabstop=4 shiftwidth=4: */
  1363. SHAR_EOF
  1364. $TOUCH -am 1224222990 'ecufork.c' &&
  1365. chmod 0644 ecufork.c ||
  1366. echo 'restore of ecufork.c failed'
  1367. Wc_c="`wc -c < 'ecufork.c'`"
  1368. test 12087 -eq "$Wc_c" ||
  1369.     echo 'ecufork.c: original size 12087, current size' "$Wc_c"
  1370. # ============= ecuicmaux.c ==============
  1371. echo 'x - extracting ecuicmaux.c (Text)'
  1372. sed 's/^X//' << 'SHAR_EOF' > 'ecuicmaux.c' &&
  1373. X/*+-------------------------------------------------------------------------
  1374. X    ecuicmaux.c -- ecuicmd.c auxiliary functions
  1375. X    wht@n4hgf.Mt-Park.GA.US
  1376. X
  1377. X  Defined functions:
  1378. X    icmd_escape_str()
  1379. X    display_ascii_names()
  1380. X    nlin_nlout_control(token,narg,arg)
  1381. X    icmd_conversion(token,narg,arg)
  1382. X    icmd_log(token,narg,arg)
  1383. X
  1384. X--------------------------------------------------------------------------*/
  1385. X/*+:EDITS:*/
  1386. X/*:08-14-1990-20:40-wht@n4hgf-ecu3.00-flush old edit history */
  1387. X
  1388. X#include "ecu.h"
  1389. X#include "ecuerror.h"
  1390. X#include "ecucmd.h"
  1391. X
  1392. X#if !defined(M_XENIX) || defined(M_UNIX)
  1393. Xextern int cmd_escape;        /* icmd escape */
  1394. X#endif
  1395. Xextern int rcvr_pid;
  1396. X
  1397. Xchar rcvr_log_file[256];    /* if rcvr_log!= 0,log filename */
  1398. Xint rcvr_log = 0;            /* rcvr log active if != 0 */
  1399. Xint rcvr_log_gen_title = 0;    /* gen log header on next open (rcvr process) */
  1400. XFILE *rcvr_log_fp;            /* rcvr log file */
  1401. Xint rcvr_log_append = 1;
  1402. Xint rcvr_log_raw = 0;
  1403. Xint rcvr_log_flusheach = 0;
  1404. X
  1405. X/*+-------------------------------------------------------------------------
  1406. X    icmd_escape_str()
  1407. X--------------------------------------------------------------------------*/
  1408. Xchar *
  1409. Xicmd_escape_str()
  1410. X{
  1411. X#if defined(M_XENIX) || defined(M_UNIX)
  1412. X    return("HOME ");
  1413. X#else
  1414. Xchar *make_char_graphic();
  1415. X    return(make_char_graphic(cmd_escape,0));
  1416. X#endif
  1417. X}    /* end of icmd_escape_str */
  1418. X
  1419. X/*+-----------------------------------------------------------------------
  1420. X    display_ascii_names()
  1421. X------------------------------------------------------------------------*/
  1422. Xvoid
  1423. Xdisplay_ascii_names()
  1424. X{
  1425. Xregister intval;
  1426. X
  1427. X    for(intval = 0; intval < 32; intval++)
  1428. X    {
  1429. X        ff(se,"%s %3d %03o %02x ^%c | ",hex_to_ascii_name((intval)),
  1430. X                (intval),(intval),(intval),(intval) |0x40);
  1431. X        ff(se,"    %3d %03o %02x  %c | ",
  1432. X                intval+32,intval+32,intval+32,intval+32);
  1433. X        ff(se,"    %3d %03o %02x  %c | ",
  1434. X                intval+64,intval+64,intval+64,intval+64);
  1435. X        if(intval != 31)
  1436. X        {
  1437. X            ff(se,"    %3d %03o %02x  %c\r\n",
  1438. X                    intval+96,intval+96,intval+96,intval+96);
  1439. X        }
  1440. X        else
  1441. X        {
  1442. X            ff(se,"    %3d %03o %02x  ^?\r\n",
  1443. X                    intval+96,intval+96,intval+96);
  1444. X        }
  1445. X    }
  1446. X
  1447. X}    /* end of display_ascii_names */
  1448. X
  1449. X/*+-------------------------------------------------------------------------
  1450. X    icmd_conversion(token,narg,arg)
  1451. X--------------------------------------------------------------------------*/
  1452. Xvoid
  1453. Xicmd_conversion(token,narg,arg)
  1454. Xint token;
  1455. Xint narg;
  1456. Xchar **arg;
  1457. X{
  1458. Xregister itmp;
  1459. X
  1460. X    switch(token)
  1461. X    {
  1462. X    case CTxa:
  1463. X    case CToa:
  1464. X    case CTda:
  1465. X        if(narg > 1)
  1466. X        {
  1467. X        int result;
  1468. X        char format[4];
  1469. X            sprintf(format,"%%%c",to_lower(*arg[0]));
  1470. X            if(sscanf(arg[1],format,&result) == 0)
  1471. X            {
  1472. X                ff(se,"  invalid argument\r\n");
  1473. X                return;
  1474. X            }
  1475. X            result &= 0xFF;
  1476. X            if(result == ' ')
  1477. X                ff(se," == ' ' 0x20\r\n",make_char_graphic(result,1));
  1478. X            else
  1479. X                ff(se," == %s\r\n",make_char_graphic(result,1));
  1480. X        }
  1481. X        else
  1482. X        {
  1483. X            ff(se,"\r\n");
  1484. X            display_ascii_names();
  1485. X        }
  1486. X        break;
  1487. X    case CTax:
  1488. X        if(arg[1] == (char *)0)
  1489. X        {
  1490. X            ff(se,"\r\n");
  1491. X            display_ascii_names();
  1492. X            break;
  1493. X        }
  1494. X        switch(strlen(arg[1]))
  1495. X        {
  1496. X            case 1:
  1497. X                ff(se," == 0x%02x\r\n",*arg[1]);
  1498. X                break;
  1499. X            case 2:
  1500. X                if(*arg[1] == '^')
  1501. X                {
  1502. X                    itmp = to_upper(*(arg[1] + 1));
  1503. X                    if((itmp < '@') || (itmp > '_'))
  1504. X                    {
  1505. X                        ff(se,"  not a valid control character\r\n");
  1506. X                        return;
  1507. X                    }
  1508. X                    itmp &= 0x1F;
  1509. X                    ff(se," == 0x%02x %s\r\n",itmp,make_char_graphic(itmp,1));
  1510. X                    break;
  1511. X                }    /* else fall thru */
  1512. X            case 3:
  1513. X                if((itmp = ascii_name_to_hex(arg[1])) > -1)
  1514. X                {
  1515. X                    ff(se," == 0x%02x %s\r\n",itmp,make_char_graphic(itmp,1));
  1516. X                    break;
  1517. X                }    /* else fall thru */
  1518. X            default:
  1519. X                ff(se,"  invalid ... examples of valid parameters:\r\n");
  1520. X                ff(se,"        ^A ETX  or  printable character\r\n");
  1521. X                break;
  1522. X        }
  1523. X        break;
  1524. X    default:
  1525. X        ff(se,"  invalid command\r\n");
  1526. X    }
  1527. X}    /* end of icmd_conversion */
  1528. X
  1529. X/*+-------------------------------------------------------------------------
  1530. X    icmd_log(token,narg,arg)
  1531. X--------------------------------------------------------------------------*/
  1532. Xint
  1533. Xicmd_log(token,narg,arg)
  1534. Xint token;
  1535. Xint narg;
  1536. Xchar **arg;
  1537. X{
  1538. Xregister itmp;
  1539. Xregister itmp2;
  1540. X
  1541. X    switch(token)
  1542. X    {
  1543. X    case CTloff:
  1544. X        goto LOG_OFF;
  1545. X        break;
  1546. X#if defined(M_XENIX) || defined(M_UNIX)
  1547. X    case CTllp:
  1548. X        icmd("log /dev/lp1");
  1549. X#endif
  1550. X        break;
  1551. X    case CTlog:
  1552. X        if(narg > 1)
  1553. X        {
  1554. X            if(minunique("off",arg[1],3))
  1555. X            {
  1556. XLOG_OFF:
  1557. X                if(rcvr_log == 0)    /* "off",but not logging */
  1558. X                    goto RECORD_REPORT;
  1559. X                ff(se,"\r\nlogging concluded (file %s)\r\n",rcvr_log_file);
  1560. X                shmx_set_rcvr_log("",0,0,0);
  1561. X                rcvr_log = 0;
  1562. X                rcvr_log_file[0] = 0;
  1563. X                return(0);
  1564. X            }
  1565. X/* turning logging on */
  1566. X            itmp2 = -1;
  1567. X            rcvr_log_append = 1;
  1568. X            rcvr_log_raw = 0;
  1569. X            for(itmp = 1; itmp < narg; itmp++)
  1570. X            {
  1571. X                if(*arg[itmp] == '-')
  1572. X                {
  1573. X                    switch(arg[itmp][1])
  1574. X                    {
  1575. X                        case 's': rcvr_log_append = 0; break;
  1576. X                        case 'r': rcvr_log_raw = 1; break;
  1577. X                        case 'f': rcvr_log_flusheach = 1; break;
  1578. X                        default:
  1579. X                            ff(se,"   unrecognized switch -%c\r\n",
  1580. X                                        arg[itmp][1]);
  1581. X                            log_cmd_usage();
  1582. X                            return(eFATAL_ALREADY);
  1583. X                    }
  1584. X                }
  1585. X                else
  1586. X                {
  1587. X                    if(itmp2 > 0)
  1588. X                    {
  1589. X                        ff(se,"   too many positional arguments\r\n");
  1590. X                        log_cmd_usage();
  1591. X                        return(eFATAL_ALREADY);
  1592. X                    }
  1593. X                    itmp2 = itmp;
  1594. X                }
  1595. X            }
  1596. X            if(itmp2 < 0)
  1597. X            {
  1598. X                ff(se,"   no log file name specified\r\n");
  1599. X                log_cmd_usage();
  1600. X                return(eFATAL_ALREADY);
  1601. X            }
  1602. X            if(arg[itmp2][0] != '/')    /* if log file not full path, ... */
  1603. X            {                            /* ... supply current directory */
  1604. X                get_curr_dir(rcvr_log_file,
  1605. X                    sizeof(rcvr_log_file) - strlen(arg[itmp2]) - 2);
  1606. X                strcat(rcvr_log_file,"/");
  1607. X                strcat(rcvr_log_file,arg[itmp2]);
  1608. X            }
  1609. X            else
  1610. X                strcpy(rcvr_log_file,arg[itmp2]);
  1611. X
  1612. X            /* try to open the file if we can */
  1613. X            rcvr_log_fp = fopen(rcvr_log_file,"a");
  1614. X            if(rcvr_log_fp != NULL)        /* if success */
  1615. X            {
  1616. X                fclose(rcvr_log_fp);
  1617. X                rcvr_log_fp = NULL;
  1618. X                rcvr_log = 1;
  1619. X                shmx_set_rcvr_log(rcvr_log_file,rcvr_log_append,rcvr_log_raw,
  1620. X                    rcvr_log_flusheach);
  1621. X            }
  1622. X            else        /* xmtr() could not open file */
  1623. X            {
  1624. X                ff(se,"   could not open ");
  1625. X                perror(rcvr_log_file);
  1626. X                ff(se,"\r\n");
  1627. X                return(eFATAL_ALREADY);
  1628. X            }
  1629. X            rcvr_log_append = 1;
  1630. X        }    /* end of if argument to command */
  1631. X
  1632. XRECORD_REPORT:
  1633. X        if(rcvr_log)
  1634. X        {
  1635. X            ff(se,"\r\n%sing received %s text to\r\n%s\r\n",
  1636. X                (rcvr_log_append) ? "append" : "writ",
  1637. X                (rcvr_log_raw)    ? "raw"    : "filtered",
  1638. X                rcvr_log_file);
  1639. X            ff(se,"use \"%slog off\" to stop logging\r\n",
  1640. X                    icmd_escape_str());
  1641. X        }
  1642. X        else
  1643. X        {
  1644. X            ff(se,"   not logging.\r\n");
  1645. X            ff(se,"use \"%slog <filename>\" to start logging\r\n",
  1646. X                    icmd_escape_str());
  1647. X        }
  1648. X        break;
  1649. X    default:
  1650. X        ff(se,"  invalid command\r\n");
  1651. X        return(eFATAL_ALREADY);
  1652. X    }
  1653. X    return(0);
  1654. X}    /* end of icmd_log */
  1655. X
  1656. X/*+-------------------------------------------------------------------------
  1657. X    nlin_nlout_control(token,narg,arg)
  1658. X--------------------------------------------------------------------------*/
  1659. Xvoid
  1660. Xnlin_nlout_control(token,narg,arg)
  1661. Xint token;
  1662. Xint narg;
  1663. Xchar **arg;
  1664. X{
  1665. X    switch(token)
  1666. X    {
  1667. X    case CTnlin:
  1668. X        if(narg != 1)
  1669. X            shm->Ladd_nl_incoming = yes_or_no(arg[1]);
  1670. X        ff(se,"  %sappending NL to incoming CR\r\n",
  1671. X            (shm->Ladd_nl_incoming) ? "" : "not ");
  1672. X        break;
  1673. X    case CTnlout:
  1674. X        if(narg != 1)
  1675. X            shm->Ladd_nl_outgoing = yes_or_no(arg[1]);
  1676. X        ff(se,"  %sappending NL to outgoing CR\r\n",
  1677. X            (shm->Ladd_nl_outgoing) ? "" : "not ");
  1678. X        break;
  1679. X    default:
  1680. X    case CTnl:
  1681. X        ff(se,"  incoming: %s  outgoing: %s\r\n",
  1682. X            (shm->Ladd_nl_incoming) ? "CR/LF" : "CR",
  1683. X            (shm->Ladd_nl_outgoing) ? "CR/LF" : "CR");
  1684. X        break;
  1685. X    }
  1686. X
  1687. X}    /* end of nlin_nlout_control */
  1688. X
  1689. X/* end of ecuicmaux.c */
  1690. X/* vi: set tabstop=4 shiftwidth=4: */
  1691. SHAR_EOF
  1692. $TOUCH -am 1224224790 'ecuicmaux.c' &&
  1693. chmod 0644 ecuicmaux.c ||
  1694. echo 'restore of ecuicmaux.c failed'
  1695. Wc_c="`wc -c < 'ecuicmaux.c'`"
  1696. test 7552 -eq "$Wc_c" ||
  1697.     echo 'ecuicmaux.c: original size 7552, current size' "$Wc_c"
  1698. # ============= ecuicmd.c ==============
  1699. echo 'x - extracting ecuicmd.c (Text)'
  1700. sed 's/^X//' << 'SHAR_EOF' > 'ecuicmd.c' &&
  1701. X/*+-----------------------------------------------------------------------
  1702. X    ecuicmd.c - ECU interactive command handler
  1703. X    wht@n4hgf.Mt-Park.GA.US
  1704. X
  1705. X  Defined functions:
  1706. X    icmd(icmd_cmd)
  1707. X    icmd_do_proc(narg,arg)
  1708. X    search_cmd_list(cmd_list,cmd)
  1709. X
  1710. X------------------------------------------------------------------------*/
  1711. X/*+:EDITS:*/
  1712. X/*:12-24-1990-04:31-wht@n4hgf-experimental esio driver command */
  1713. X/*:08-14-1990-20:40-wht@n4hgf-ecu3.00-flush old edit history */
  1714. X
  1715. X#include "ecu.h"
  1716. X#include "esd.h"
  1717. X#include "ecufkey.h"
  1718. X#include "patchlevel.h"
  1719. X
  1720. X#define NEED_P_CMD
  1721. X#include "ecucmd.h"
  1722. X
  1723. Xchar *icmd_escape_str();
  1724. X
  1725. Xextern KDE keyset_table[];
  1726. Xextern char *makedate;
  1727. Xextern char curr_dir[];
  1728. Xextern char hello_str[];
  1729. Xextern char keyset_name[];
  1730. Xextern char rcvr_log_file[];    /* if rcvr_log!= 0,log filename */
  1731. Xextern int interrupt;
  1732. Xextern int current_ttymode;
  1733. Xextern int errno;
  1734. Xextern int proc_level;
  1735. Xextern int proctrace;
  1736. Xextern int rcvr_log;            /* rcvr log active if != 0 */
  1737. Xextern int rcvr_log_append;    /* if true, append, else scratch */
  1738. Xextern int rcvr_log_raw;        /* if true, log all, else filter ctl chrs */
  1739. Xextern int rcvr_pid;
  1740. Xextern ulong colors_current;
  1741. Xextern FILE *plog_fp;
  1742. Xextern ESD  *plog_name;
  1743. Xextern char screen_dump_file_name[];
  1744. X
  1745. Xint protocol_log_packets = 0;
  1746. Xint want_bell_notify = 1;    /* want bell notify */
  1747. Xint cmd_escape;
  1748. X
  1749. X/*+-------------------------------------------------------------------------
  1750. X    search_cmd_list(cmd_list,cmd)
  1751. Xreturns -1 if cmd not found or insufficient chars for match
  1752. Xelse token value for command
  1753. Xproc-only commands have 'min' values 0
  1754. X--------------------------------------------------------------------------*/
  1755. Xsearch_cmd_list(cmd_list,cmd)
  1756. Xregister P_CMD *cmd_list;
  1757. Xregister char *cmd;
  1758. X{
  1759. X    while(cmd_list->token != -1)
  1760. X    {
  1761. X        if(cmd_list->min && minunique(cmd_list->cmd,cmd,cmd_list->min))
  1762. X            return(cmd_list->token);
  1763. X        cmd_list++;
  1764. X    }
  1765. X    return(-1);
  1766. X
  1767. X}    /* end of search_cmd_list */
  1768. X
  1769. X/*+-------------------------------------------------------------------------
  1770. X    icmd_do_proc(narg,arg)
  1771. X--------------------------------------------------------------------------*/
  1772. Xicmd_do_proc(narg,arg)
  1773. Xint narg;
  1774. Xchar **arg;
  1775. X{
  1776. Xregister erc;
  1777. Xulong colors_at_entry = colors_current;
  1778. X
  1779. X    kill_rcvr_process(SIGUSR1);
  1780. X    ttymode(2);
  1781. X    erc = do_proc(narg,arg);
  1782. X    proc_file_reset();
  1783. X    ttymode(1);
  1784. X    interrupt = 0;
  1785. X    setcolor(colors_notify);
  1786. X    ff(se,"[procedure finished]");
  1787. X    setcolor(colors_at_entry);
  1788. X    ff(se,"\r\n");
  1789. X    start_rcvr_process(0);
  1790. X    return(erc);
  1791. X}    /* end of icmd_do_proc */
  1792. X
  1793. X/*+-----------------------------------------------------------------------
  1794. X    icmd(cmd)
  1795. X This function implements the built in commands
  1796. X It returns non-zero if program should terminate
  1797. X------------------------------------------------------------------------*/
  1798. Xint
  1799. Xicmd(icmd_cmd)
  1800. Xregister char *icmd_cmd;
  1801. X{
  1802. X
  1803. X#define ARG_MAX_QUAN 40
  1804. Xchar *arg[ARG_MAX_QUAN];
  1805. Xchar cmd[128];
  1806. Xint itmp;
  1807. Xint token;
  1808. Xint narg = 0;
  1809. XESD *tesd;
  1810. Xchar s80[80];
  1811. Xchar *epoch_secs_to_str();
  1812. Xlong atol();
  1813. Xlong rcvr_chars;
  1814. Xlong rcvr_chars_this_connect;
  1815. Xchar *find_procedure();
  1816. Xchar *xon_status();
  1817. X
  1818. X    icmd_history_add(icmd_cmd);        /* add to history list */
  1819. X    strcpy(cmd,icmd_cmd);            /* get local copy of cmd string */
  1820. X    switch(cmd[0]) 
  1821. X    {
  1822. X        case '.':        /* exit xmtr() (generally program too) */
  1823. X            ff(se,"  disconnecting from line %s\r\n",shm->Lline);
  1824. X            return(1);
  1825. X        case '!':
  1826. X        case '$':
  1827. X        case '>':
  1828. X            ff(se,"\r\n");
  1829. X            shell(cmd);
  1830. X            return(0);
  1831. X        case '-':
  1832. X            ff(se,"\r\n");
  1833. X            exec_cmd(&cmd[1]);
  1834. X            return(0);
  1835. X        case '^':
  1836. X            ff(se,"\r\n");
  1837. X            phrase_help();
  1838. X            return(0);
  1839. X        case '?':
  1840. X            icmd_help(0,(char **)0);
  1841. X            return(0);
  1842. X#ifdef DEBUG_SHM_SCREEN
  1843. X        case '@':
  1844. X            {
  1845. X            FILE *fp = fopen("/tmp/screen","w");
  1846. X            int y,x;
  1847. X            char *cptr = (char *)shm->screen;
  1848. X                for(y = 0; y < 43; y++)
  1849. X                {
  1850. X                    for(x = 0; x < 80; x++)
  1851. X                        fputc(*cptr++,fp);
  1852. X                    fputc('\n',fp);
  1853. X                }
  1854. X                fclose(fp);
  1855. X            }
  1856. X            break;
  1857. X#endif
  1858. X        default:
  1859. X            break;
  1860. X    }
  1861. X
  1862. X/* not single character argument */
  1863. X    build_arg_array(cmd,arg,ARG_MAX_QUAN,&narg);
  1864. X
  1865. X/* handle phrases */
  1866. X    if(isdigit(*arg[0]))
  1867. X    {
  1868. X        phrases(narg,arg);
  1869. X        return(0);
  1870. X    }
  1871. X
  1872. X/* search command list */
  1873. X    if((token = search_cmd_list(icmd_cmds,arg[0])) < 0)
  1874. X    {
  1875. X        ff(se,"\r\n");
  1876. X        if(find_procedure(arg[0]))
  1877. X        {
  1878. X            icmd_do_proc(narg,arg);
  1879. X            return(0);
  1880. X        }
  1881. X        ff(se,"no such command or procedure ... %s? for help\r\n",
  1882. X            icmd_escape_str());
  1883. X        return(0);
  1884. X    }
  1885. X
  1886. X    switch(token)
  1887. X    {                    /* keep alphabetized PLEASE */
  1888. X        case CTrx:
  1889. X        case CTry:
  1890. X        case CTrz:
  1891. X        case CTrk:
  1892. X        case CTrs:
  1893. X        receive_files_from_remote(narg,arg);
  1894. X        break;
  1895. X
  1896. X        case CTsx:
  1897. X        case CTsy:
  1898. X        case CTsz:
  1899. X        case CTsk:
  1900. X        case CTss:
  1901. X        send_files_to_remote(narg,arg);
  1902. X        break;
  1903. X
  1904. X        case CTbaud:
  1905. X        if(narg == 1)
  1906. X            ff(se,"   baud rate is %u\r\n",shm->Lbaud);
  1907. X        else
  1908. X        {
  1909. X            itmp = atoi(arg[1]);
  1910. X            if(!lnew_baud_rate(itmp))
  1911. X                ff(se,"   baud rate set to %u\r\n",shm->Lbaud);
  1912. X            else
  1913. X            {
  1914. X                ff(se,"   invalid baud rate: %u\r\n",itmp);
  1915. X                ff(se,"valid rates: 110,300,600,1200,2400,4800,9600,19200\r\n");
  1916. X            }
  1917. X        }
  1918. X        break;
  1919. X
  1920. X        case CTbreak:
  1921. X        lbreak();
  1922. X        ff(se,"   break sent\r\n");
  1923. X        break;
  1924. X
  1925. X        case CTcd:
  1926. X        change_directory(arg[1],(narg == 1) ? 0 : 1);
  1927. X        break;
  1928. X
  1929. X        case CTclrx:
  1930. X        lclear_xmtr_xoff();
  1931. X        break;
  1932. X
  1933. X        case CTdial:
  1934. X        if(narg > 1)
  1935. X        {
  1936. X            ff(se,"\r\n");
  1937. X            strcpy(shm->Llogical,arg[1]);
  1938. X            if(!lookup_logical_telno())
  1939. X                ff(se,"No such entry. Try 'dial' with no arguments\r\n");
  1940. X            else
  1941. X            {
  1942. X                if(isdigit(shm->Llogical[0]) ||
  1943. X                    !find_procedure(shm->Llogical))
  1944. X                    DCE_dial();
  1945. X                else
  1946. X                {
  1947. X                    arg[0] = shm->Llogical;
  1948. X                    arg[1] = "!INTERACTIVE";
  1949. X                    icmd_do_proc(2,arg);
  1950. X                }
  1951. X            }
  1952. X        }
  1953. X        else
  1954. X        {
  1955. X            pde_list_manager();
  1956. X        }
  1957. X        break;
  1958. X
  1959. X        case CTdo:
  1960. X        ff(se,"\r\n");
  1961. X        icmd_do_proc(narg - 1,&arg[1]);
  1962. X        break;
  1963. X
  1964. X        case CTptrace:
  1965. X        if(narg > 1)
  1966. X            proctrace = yes_or_no(arg[1]);
  1967. X        ff(se,"  procedure trace %s", proctrace ? "on" : "off");
  1968. X        if(proctrace > 1)
  1969. X            ff(se," (%d)",proctrace);
  1970. X        ff(se,"\r\n");
  1971. X        break;
  1972. X
  1973. X        case CTpcmd:
  1974. X        itmp = strlen(arg[0]);
  1975. X        if((tesd = make_esd(256)) == (ESD *)0)
  1976. X        {
  1977. X            ff(se,"  no memory!!?!\r\n");
  1978. X            break;
  1979. X        }
  1980. X        strcpy(tesd->pb,icmd_cmd + itmp + 1);
  1981. X        tesd->cb = strlen(tesd->pb);
  1982. X        ff(se,"\r\n");
  1983. X        kill_rcvr_process(SIGUSR1);
  1984. X        ttymode(2);
  1985. X        if(itmp = execute_esd(tesd))
  1986. X        {
  1987. X            proc_error(itmp);
  1988. X            show_esd(tesd,"");
  1989. X        }
  1990. X        free_esd(tesd);
  1991. X        ttymode(1);
  1992. X        start_rcvr_process(0);
  1993. X        break;
  1994. X
  1995. X        case CTplog:
  1996. X        fputs("  ",se);
  1997. X        if(narg > 1)
  1998. X        {
  1999. X            if(!strcmp(arg[1],"off"))
  2000. X                plog_control((char *)0);
  2001. X            else
  2002. X                plog_control(arg[1]);
  2003. X        }
  2004. X        
  2005. X        if(plog_fp)
  2006. X            ff(se,"procedure logging: %s\r\n",plog_name->pb);
  2007. X        else
  2008. X            fputs("procedure logging off\r\n",se);
  2009. X        break;
  2010. X
  2011. X        case CTduplex:
  2012. X        if(narg > 1)
  2013. X        {
  2014. X            switch(to_lower(*arg[1]))
  2015. X            {
  2016. X                case 'f': shm->Lfull_duplex = 1; ff(se,"  now "); break;
  2017. X                case 'h': shm->Lfull_duplex = 0; ff(se,"  now "); break;
  2018. X                default: ff(se,
  2019. X"\r\nfirst argument character must be F or H for full or half duplex\r\n");
  2020. X                    break;
  2021. X            }
  2022. X        }
  2023. X        else        /* no argument */
  2024. X            ff(se,"  currently ");
  2025. X
  2026. X        ff(se,"%s duplex\r\n",(shm->Lfull_duplex) ? "full" : "half");
  2027. X        break;
  2028. X
  2029. X        case CTexit:
  2030. X        ff(se,"  disconnecting from line %s\r\n",shm->Lline);
  2031. X        return(1);
  2032. X
  2033. X        case CTfi:
  2034. X        file_insert_to_line(narg,arg);
  2035. X        break;
  2036. X
  2037. X        case CThangup:
  2038. X        ff(se,"   hanging up ... ");
  2039. X        DCE_hangup();
  2040. X        ff(se,"done\r\n");
  2041. X        break;
  2042. X
  2043. X        case CThelp:
  2044. X        icmd_help(narg,arg);
  2045. X        break;
  2046. X
  2047. X        case CTsdname:
  2048. X        if(narg > 1)
  2049. X        {
  2050. X        char *new_file_name;
  2051. X
  2052. X            itmp = 0;    /* do not need to free(new_file_name) */
  2053. X            if(find_shell_chars(arg[1]))
  2054. X            {
  2055. X
  2056. X                if(expand_cmd_with_wildlist(arg[1],&new_file_name))
  2057. X                {
  2058. X                    ff(se,"  %s\r\n",new_file_name);
  2059. X                    break;
  2060. X                }
  2061. X                itmp = 1;    /* need to free(new_file_name) */
  2062. X            }
  2063. X            else
  2064. X                new_file_name = arg[1];
  2065. X
  2066. X            screen_dump_file_name[0] = 0;
  2067. X            if(*new_file_name != '/')
  2068. X            {
  2069. X                strcpy(screen_dump_file_name,curr_dir);
  2070. X                strcat(screen_dump_file_name,"/");
  2071. X            }
  2072. X            strcat(screen_dump_file_name,arg[1]);
  2073. X            if(itmp)
  2074. X                free(new_file_name);
  2075. X        }
  2076. X        ff(se,"\r\nscreen dump name: %s\r\n",screen_dump_file_name);
  2077. X        break;
  2078. X
  2079. X        case CTlog:
  2080. X        case CTloff:
  2081. X        case CTllp:
  2082. X        icmd_log(token,narg,arg);
  2083. X        break;
  2084. X
  2085. X        case CTnl:
  2086. X        case CTnlin:
  2087. X        case CTnlout:
  2088. X        nlin_nlout_control(token,narg,arg);
  2089. X        break;
  2090. X
  2091. X        case CTparity:
  2092. X        if(narg > 1)
  2093. X        {
  2094. X            switch(to_lower(*arg[1]))
  2095. X            {
  2096. X                case 'n':
  2097. X                    shm->Lparity = 0; break;
  2098. X                case 'e':
  2099. X                case 'o':
  2100. X                    shm->Lparity = to_lower(*arg[1]); break;
  2101. X                default:
  2102. X                    ff(se,"   unrecognized parity: %c\r\n",*arg[1]);
  2103. X                    goto PARITY_DONE;
  2104. X            }
  2105. X            lset_parity(1);
  2106. X        }
  2107. X        ff(se,"   parity set to %c\r\n",
  2108. X            (shm->Lparity) ? to_upper(shm->Lparity) : 'N');
  2109. XPARITY_DONE: ;
  2110. X        break;
  2111. X
  2112. X        case CTpid:
  2113. X        ff(se,": xmtr %d, rcvr: %d, parent: %d, group: %d\r\n",
  2114. X            getpid(0),rcvr_pid,getppid(0),getpgrp(0));
  2115. X        break;
  2116. X
  2117. X        case CTpwd:
  2118. X        fputs(" ",se);
  2119. X        tcap_stand_out();
  2120. X        ff(se," %s ",curr_dir);
  2121. X        tcap_stand_end();
  2122. X        fputs("\r\n",se);
  2123. X        break;
  2124. X
  2125. X        case CTredial:
  2126. X        (void)DCE_redial(arg,narg);
  2127. X        break;
  2128. X
  2129. X        case CTrev:
  2130. X        fputs("\r\n",se);
  2131. X        fputs(hello_str,se);
  2132. X        fputs("\r\n",se);
  2133. X        ff(se,"%s\r\n",makedate);
  2134. X        break;
  2135. X
  2136. X        case CTtime:
  2137. X        get_tod(4,cmd);
  2138. X        ff(se,": %s\r\n",cmd);
  2139. X        break;
  2140. X
  2141. X        case CTts:
  2142. X        ff(se,"\r\n");
  2143. X        sprintf(s80,"TTYIN %s (ttymode=%d)",get_ttyname(),current_ttymode);
  2144. X        disp_line_termio(TTYIN,s80);
  2145. X        ff(se,"\r\n");
  2146. X        sprintf(s80,"comm line %s",shm->Lline);
  2147. X        disp_line_termio(shm->Liofd,s80);
  2148. X        break;
  2149. X
  2150. X#if    defined(ESIO_IN_USE)
  2151. X        case CTesio:
  2152. X        icmd_esio(narg,arg);
  2153. X        break;
  2154. X#endif
  2155. X        case CTtty:
  2156. X        ff(se,"   %s\r\n",get_ttyname());
  2157. X        break;
  2158. X
  2159. X        case CTda:
  2160. X        case CToa:
  2161. X        case CTxa:
  2162. X        case CTax:
  2163. X        icmd_conversion(token,narg,arg);
  2164. X        break;
  2165. X
  2166. X        case CTbn:
  2167. X        if(narg > 1)
  2168. X        {
  2169. X            want_bell_notify = yes_or_no(arg[1]);
  2170. X            shmx_set_rcvr_bn(want_bell_notify);
  2171. X        }
  2172. X        ff(se,"  bell notify %s%s\r\n",
  2173. X                    want_bell_notify ? "on" : "off",
  2174. X                    (want_bell_notify == 2) ? ": ring on incoming char" : "");
  2175. X        break;
  2176. X
  2177. X        case CTrtscts:
  2178. X        if(narg > 1)
  2179. X        {
  2180. X            lRTSCTS_control(yes_or_no(arg[1]));
  2181. X        }
  2182. X        ff(se,"  RTS %s CTS %s\r\n",
  2183. X            (Ltermio.c_cflag & RTSFLOW) ? "on" : "off",
  2184. X            (Ltermio.c_cflag & CTSFLOW) ? "on" : "off");
  2185. X        break;
  2186. X
  2187. X        case CTfkey:
  2188. X        if(narg < 2)
  2189. X            keyset_display();
  2190. X        else
  2191. X        {
  2192. X            switch(keyset_read(arg[1]))
  2193. X            {
  2194. X                case  0: keyset_display(); break;
  2195. X                case -1: ff(se," cannot find ~/.ecu/keys\r\n"); break;
  2196. X                case -2: ff(se," not found in ~/.ecu/keys\r\n"); break;
  2197. X            }
  2198. X        }
  2199. X        break;
  2200. X
  2201. X        case CTstat:
  2202. X        ff(se,"\r\n\r\nDate/time");
  2203. X        get_tod(4,cmd);
  2204. X        ff(se,": %s\r\n",cmd);
  2205. X        ff(se,"Console: %s  communications line: %s  ",
  2206. X            get_ttyname(),shm->Lline);
  2207. X        ff(se,"%u-%c-1\r\n",shm->Lbaud,
  2208. X            (shm->Lparity) ? to_upper(shm->Lparity) : 'N');
  2209. X        if(shm->Lmodem_off_hook)
  2210. X        {
  2211. X            ff(se,"Connected to %s: %s (%s)\r\n",
  2212. X                shm->Lrname,shm->Ldescr,shm->Ltelno);
  2213. X            ff(se,"at %s (elapsed %s)\r\n",
  2214. X                epoch_secs_to_str(shm->Loff_hook_time,1,s80),
  2215. X                get_elapsed_time(time((long *)0) - shm->Loff_hook_time));
  2216. X        }
  2217. X        ff(se,"Current directory: %s\r\n",curr_dir);
  2218. X        ff(se,"Total chars transmitted: %ld",shm->xmit_chars);
  2219. X        if(shm->Lmodem_off_hook)
  2220. X            ff(se," (since CONNECT %ld)\r\n",
  2221. X                shm->xmit_chars_this_connect);
  2222. X        else
  2223. X            fputs("\r\n",se);
  2224. X        shmx_rc_report(&rcvr_chars,&rcvr_chars_this_connect);
  2225. X        ff(se,"Total chars received:    %ld",rcvr_chars);
  2226. X        if(shm->Lmodem_off_hook)
  2227. X            ff(se," (since CONNECT %ld)\r\n",rcvr_chars_this_connect);
  2228. X        else
  2229. X            fputs("\r\n",se);
  2230. X        if(keyset_name[0])
  2231. X            ff(se,"Function key set '%s' loaded\r\n",keyset_name);
  2232. X        else
  2233. X            ff(se,"No function key set loaded\r\n");
  2234. X        if(rcvr_log)
  2235. X            ff(se,"Session log open: %s (%s mode)\r\n",
  2236. X                rcvr_log_file,(rcvr_log_raw) ? "raw" : "filtered");
  2237. X        else
  2238. X            ff(se,"Session logging not active\r\n");
  2239. X        ff(se,"Bell notify is %s\r\n",(want_bell_notify) ? "on" : "off");
  2240. X        ff(se,"Duplex: %s\r\n",(shm->Lfull_duplex) ? "full" : "half");
  2241. X        ff(se,"CR conversion:  incoming %s  outgoing %s\r\n",
  2242. X            (shm->Ladd_nl_incoming) ? "CR/LF" : "CR",
  2243. X            (shm->Ladd_nl_outgoing) ? "CR/LF" : "CR");
  2244. X        fputs("\r\n",se);
  2245. X        break;
  2246. X
  2247. X        case CTxlog:
  2248. X        if(narg > 1)
  2249. X        {
  2250. X            protocol_log_packets = yes_or_no(arg[1]);
  2251. X        }
  2252. X        ff(se,"  protocol packet logging %s\r\n",
  2253. X            (protocol_log_packets) ? "on" : "off");
  2254. X        break;
  2255. X
  2256. X        case CTxon:
  2257. X        if(narg > 1)
  2258. X        {
  2259. X            if(set_xon_xoff_by_arg(arg[1]))
  2260. X                ff(se,"  argument error\r\n");
  2261. X            else
  2262. X                ff(se,"\r\n");
  2263. X            break;
  2264. X        }
  2265. X        ff(se,"  xon/xoff flow control: %s\r\n",xon_status());
  2266. X        break;
  2267. X
  2268. X        case CTsgr:
  2269. X        send_get_response(token,narg,arg);
  2270. X        break;
  2271. X
  2272. X/*
  2273. X        case CTmkdir:
  2274. X        if(narg < 2)
  2275. X            ff(se,"  no argument\r\n");
  2276. X        if(mkdir(arg[2],0755))
  2277. X        {
  2278. X            ff(se,"  ");
  2279. X            pperror(arg[2]);
  2280. X        }
  2281. X        else
  2282. X            ff(se,"  made directory %s\r\n",arg[2]);
  2283. X        break;
  2284. X*/
  2285. X
  2286. X        case 0:
  2287. X        ff(se,"   procedure command not allowed in interactive mode\r\n");
  2288. X        break;
  2289. X
  2290. X        default:
  2291. X        do_proc(narg,arg);
  2292. X        interrupt = 0;
  2293. X        break;
  2294. X
  2295. X    }
  2296. X    return(0);        /* 0 == do not end program */
  2297. X
  2298. X}    /* end of icmd */
  2299. X
  2300. X/* end of ecuicmd.c */
  2301. X/* vi: set tabstop=4 shiftwidth=4: */
  2302. SHAR_EOF
  2303. $TOUCH -am 1224224790 'ecuicmd.c' &&
  2304. chmod 0644 ecuicmd.c ||
  2305. echo 'restore of ecuicmd.c failed'
  2306. Wc_c="`wc -c < 'ecuicmd.c'`"
  2307. test 12735 -eq "$Wc_c" ||
  2308.     echo 'ecuicmd.c: original size 12735, current size' "$Wc_c"
  2309. true || echo 'restore of ecuicmhelp.c failed'
  2310. echo End of part 3, continue with part 4
  2311. exit 0
  2312. --------------------------------------------------------------------
  2313. Warren Tucker, TuckerWare emory!n4hgf!wht or wht@n4hgf.Mt-Park.GA.US
  2314. Hacker Extraordinaire  d' async PADs,  pods,  proteins and protocols
  2315.  
  2316. exit 0 # Just in case...
  2317. -- 
  2318. Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
  2319. Sterling Software, IMD           UUCP:     uunet!sparky!kent
  2320. Phone:    (402) 291-8300         FAX:      (402) 291-4362
  2321. Please send comp.sources.misc-related mail to kent@uunet.uu.net.
  2322.